using System;
using System.Text.RegularExpressions;
using AutoMapper;

namespace Jinjia.Approve.Model.AutoMapperProfile
{
    /// <summary>
    /// 忽略大小写命名转换规则
    /// </summary>
    public class IgnoreCaseNamingConvention : INamingConvention
    {
        public string ReplaceValue(Match match) => match.Value.ToLower();
        public Regex SplittingExpression { get; } = new Regex("(\\p{Lu}+(?=$|\\p{Lu}[\\p{Ll}0-9])|\\p{Lu}?[\\p{Ll}0-9]+)");
        public string SeparatorCharacter { get; } = string.Empty;
    }

    public static class AutoMapperExtension
    {
        public static void IgnoreNullMember(this IMapperConfigurationExpression cfg)
        {
            cfg.ForAllMaps((a, b) => b.ForAllMembers(opt => opt.Condition((src, dest, sourceMember) => sourceMember != null)));
        }
        
        public static TDestination Map<TSource, TDestination>(this IMapper mapper, TDestination destination, TSource source)
        {
            return mapper.Map(source, destination);
        }
    }

    public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
    {
        public DateTime Convert(string source, DateTime destination, ResolutionContext context)
        {
            DateTime datetime = default;

            var tryParse = DateTime.TryParse(source, out var tempTime);
            if (!tryParse)
            {
                var specialFormat1 = DateTime.TryParseExact(source, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None,
                    out var specialFormatResult1);
                if (specialFormat1)
                {
                    return specialFormatResult1;
                }

                var specialFormat2 = DateTime.TryParseExact(source, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None,
                    out var specialFormatResult2);
                if (specialFormat2)
                {
                    return specialFormatResult2;
                }

                return datetime;
            }

            return tempTime;
        }
    }

    public class DecimalTypeConverter : ITypeConverter<string, decimal>
    {
        public decimal Convert(string source, decimal destination, ResolutionContext context)
        {
            decimal value = default;
            try
            {
                value = System.Convert.ToDecimal(source);
            }
            catch (Exception)
            {
                // ignored
            }

            return value;
        }
    }

    public class IntTypeConverter : ITypeConverter<string, int>
    {
        public int Convert(string source, int destination, ResolutionContext context)
        {
            int.TryParse(source, out var value);
            return value;
        }
    }
}